package com.googlecode.KeepInTouch;

import java.util.Collection;
import java.util.HashMap;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CallLog;
import android.provider.ContactsContract.PhoneLookup;

public class CallLogAnalyser {
	public static final String TAG = "CallLogAnalyse";
	public static final Uri uri = CallLog.Calls.CONTENT_URI;
	public static final String NUMBER = "number";
	public static final String CALLS = "calls";
	public static final String DURATION_SUM = "duration_sum";
	public static final String LAST_CALL_DATE = "last_call_date";
	public static final String INCOMING_CALLS = "incoming_calls";
	public static final String INCOMING_SUM = "incoming_sum";
	public static final String INCOMING_LAST = "incoming_last";
	public static final String OUTGOING_CALLS = "outgoing_calls";
	public static final String OUTGOING_SUM = "outgoing_sum";
	public static final String OUTGOING_LAST = "outgoing_last";
	public static final String MISSED_CALLS = "missed_calls";
	public static final String MISSED_LAST = "missed_last";
	
	private static final String[] projection = new String[] {
		CallLog.Calls.NUMBER + " as " + NUMBER,
		"COUNT(_id) as " + CALLS,
		"SUM(" + CallLog.Calls.DURATION + ") as " + DURATION_SUM,
		"MAX(" + CallLog.Calls.DATE + ") as " + LAST_CALL_DATE,
		"SUM(CASE " + CallLog.Calls.TYPE + " WHEN " + CallLog.Calls.INCOMING_TYPE + " THEN 1 ELSE 0 END) as " + INCOMING_CALLS,
		"SUM(CASE " + CallLog.Calls.TYPE + " WHEN " + CallLog.Calls.INCOMING_TYPE + " THEN " + CallLog.Calls.DURATION + " ELSE 0 END) as " + INCOMING_SUM,
		"MAX(CASE " + CallLog.Calls.TYPE + " WHEN " + CallLog.Calls.INCOMING_TYPE + " THEN " + CallLog.Calls.DATE + " ELSE NULL END) as " + INCOMING_LAST,
		"SUM(CASE " + CallLog.Calls.TYPE + " WHEN " + CallLog.Calls.OUTGOING_TYPE + " THEN 1 ELSE 0 END) as " + OUTGOING_CALLS,
		"SUM(CASE " + CallLog.Calls.TYPE + " WHEN " + CallLog.Calls.OUTGOING_TYPE + " THEN " + CallLog.Calls.DURATION + " ELSE 0 END) as " + OUTGOING_SUM,
		"MAX(CASE " + CallLog.Calls.TYPE + " WHEN " + CallLog.Calls.OUTGOING_TYPE + " THEN " + CallLog.Calls.DATE + " ELSE NULL END) as " + OUTGOING_SUM,
		"SUM(CASE " + CallLog.Calls.TYPE + " WHEN " + CallLog.Calls.MISSED_TYPE + " THEN 1 ELSE 0 END) as " + MISSED_CALLS,
		"MAX(CASE " + CallLog.Calls.TYPE + " WHEN " + CallLog.Calls.MISSED_TYPE + " THEN " + CallLog.Calls.DATE + " ELSE NULL END) as " + MISSED_LAST
	};
	
	private static final String selection = "_id > 0 ) GROUP BY (" + CallLog.Calls.NUMBER;

	public static Cursor getCallLog(Context context) {
		return context.getContentResolver().query(uri, projection, selection, null, null);
	}
	
	public static Collection<ContactSummary> getSummary(Context context) {
		HashMap<Long, ContactSummary> results = new HashMap<Long, ContactSummary>();
		Cursor cursor = getCallLog(context);
		if(cursor != null) {
			if(cursor.moveToFirst()) {
				do {
					ContactSummary summary = createContactSummary(cursor, context);
					if(results.containsKey(summary.id)) {
						results.get(summary.id).merge(summary);
					}
					else {
						results.put(summary.id, summary);
					}
				} while(cursor.moveToNext());
			}
			cursor.close();
		}
		return results.values();
	}
	
	private static ContactSummary createContactSummary(Cursor cursor, Context context) {
		if(cursor != null) {
			ContactSummary summary = new ContactSummary();
			summary.calls  = cursor.getInt(1);
			summary.durationSum = cursor.getLong(2);
			summary.lastCallDate = cursor.getLong(3);
			summary.incomingCalls = cursor.getInt(4);
			summary.incomingSum = cursor.getLong(5);
			summary.lastIncomingCall = cursor.getLong(6);
			summary.outgoingCalls = cursor.getInt(7);
			summary.outgoingSum = cursor.getLong(8);
			summary.lastOutgoingCall = cursor.getLong(9);
			summary.missedCalls = cursor.getInt(10);
			summary.lastMissedCall = cursor.getLong(11);
			Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(cursor.getString(0)));
			Cursor contact = context.getContentResolver().query(uri, new String[] {PhoneLookup._ID, PhoneLookup.LOOKUP_KEY}, null, null, null);
			if(contact != null) {
				if(contact.moveToFirst()) {
					summary.id = contact.getLong(0);
					summary.lookupKey = contact.getString(1);
				}
				contact.close();
			}
			return summary;
		}
		return null;
	}

}
